package com.woldier.filesystem.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.woldier.base.exception.DoopfsException;
import com.woldier.base.model.R;
import com.woldier.base.utils.ListUtils;
import com.woldier.base.utils.UserHolder;
import com.woldier.filesystem.model.dto.RepositoryShareDto;
import com.woldier.filesystem.model.po.Repository;
import com.woldier.filesystem.service.RepositoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 有关repository的接口
 */
@RestController
@RequestMapping("/repo")
public class RepositoryController {
    /**
     * 获取用户的所有仓库
     *
     * @param username
     * @return
     */
//    @Value("${wd.hadoop.proxy.url}")
//    private String url;
//    @Autowired
//    private RestTemplate restTemplate;
//
//    @GetMapping("list")
//    public R getRepositoryList(@RequestParam String username){
//        /**
//         *发起请求
//         */
//        JSONObject object = restTemplateFileStatusesJSON(username);
//
//        /**
//         * json解析
//         */
//        FileStatuses fileStatuses = CommonRequest.JSONObject2FileStatuses(object);
//        return R.success(fileStatuses);
//    }
//
//    private  JSONObject restTemplateFileStatusesJSON(String username) {
//        JSONObject object = restTemplate.getForObject(CommonRequest.generateUrl(url, username, RequestOption.LISTSTATUS),JSONObject.class);
//        return object;
//    }

    @Autowired
    private RepositoryService repositoryService;

    @GetMapping("list")
    public R list(@RequestParam String owner, @RequestParam Integer repoType) throws DoopfsException {
        /*查询自己创建的仓库*/
        checkTypeIsNotNull(repoType);
        LambdaQueryWrapper<Repository> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Repository::getUserName, owner);
        lambdaQueryWrapper.eq(Repository::getRepoType, repoType);
        /*查数据*/
        List<Repository> list = repositoryService.list(lambdaQueryWrapper);
        /*递归查询每一个仓库，查看他被那些人分享了*/
        List<RepositoryShareDto> fileShareDtoList = new ArrayList<>();
        ListUtils.copyList(list,fileShareDtoList,RepositoryShareDto.class);
        fileShareDtoList.forEach(e -> {
            /*对于查询到的所有仓库，若不是共享的其他人的仓库，则说明是自己的仓库，查看其被哪些用户共享*/
            if(!e.getShareRepo()){
                String nameRepo = e.getNameRepo();
                LambdaQueryWrapper<Repository> lambda = new LambdaQueryWrapper<>();
                lambda.eq(Repository::getNameRepo, nameRepo);
                List<Repository> repositories = repositoryService.list(lambda);
                List<String> collect = repositories.stream().map(Repository::getUserName).collect(Collectors.toList());
                e.setSharedUserName(collect);
            }
        });
        return R.success(fileShareDtoList);
    }

    private static void checkTypeIsNotNull(Integer repoType) throws DoopfsException {
        if (repoType == null) DoopfsException.cast("pram repoType must be bot null");
    }

    @GetMapping("create")
    public R create(@RequestParam String owner, @RequestParam String repository, @RequestParam Integer repoType) throws DoopfsException {
        checkTypeIsNotNull(repoType);
        LambdaQueryWrapper<Repository> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Repository::getUserName, owner)
                .eq(Repository::getNameRepo, owner + "/" + repository);
//                .eq(Repository::getRepoType,repoType);
        List<Repository> repositoryList = repositoryService.list(lambdaQueryWrapper);
        if (!repositoryList.isEmpty()) DoopfsException.cast("已经存在");
        repositoryService.save(
                Repository.builder().
                        userName(owner).
                        nameRepo(owner + "/" + repository).
                        repoType(repoType).
                        build());
        return R.success("成功");
    }

    @GetMapping("share")
    public R share(@RequestParam String owner, @RequestParam String repository, @RequestParam String username_share,
                   @RequestParam Boolean readOnly, @RequestParam Boolean isExecutable
            , @RequestParam Integer repoType
    ) throws DoopfsException {
        /**
         * 1.先判断传入的username与token中的username是否一致
         * 2.如果不一致则不允许新建，抛出异常，不允许操作他人的
         * 3.检查仓库是否存在
         */
        checkTypeIsNotNull(repoType);
        String tokenUser = UserHolder.getTokenUser();
        /*s所有者+仓库拼接*/
        String name_repo = tokenUser + "/" + repository;

        if (owner.equals(username_share)) DoopfsException.cast("can not share repository to self");

        if (!StringUtils.isEmpty(owner) && !owner.equals(tokenUser))
            DoopfsException.cast("不能操作其他人的仓库");
        /*查看仓库是否存在*/
        //if(!repositoryService.exist(tokenUser,name_repo)) throw new BizException("操作的仓库不存在请先创建",400);
        List<Repository> self_repo = repositoryService.list(new LambdaQueryWrapper<Repository>()
                .eq(Repository::getUserName, tokenUser)
                .eq(Repository::getNameRepo, name_repo)
        );
        if (self_repo.isEmpty()) {
            DoopfsException.cast("repo \'" + repository + "\' not exist, please create it first");
        } else {
            int type = self_repo.get(0).getRepoType();
            if (type != repoType)
                DoopfsException.cast("shared repository type must be " + type + " not " + repoType);
        }

        List<Repository> list = repositoryService.list(new LambdaQueryWrapper<Repository>()
                .eq(Repository::getUserName, username_share)
                .eq(Repository::getNameRepo, name_repo)
        );
        if (list.isEmpty())
            repositoryService.save(Repository.builder()
                    .userName(username_share)
                    .nameRepo(name_repo)
                    .shareRepo(Boolean.TRUE)
                    .readOnly(readOnly)
                    .isExecutable(isExecutable)
                    .build());
        else {
            Repository repository1 = list.get(0);
            repository1.setReadOnly(readOnly);
            repository1.setIsExecutable(isExecutable);
            repository1.setRepoType(repoType);
            repositoryService.saveOrUpdate(repository1);
        }

        return R.success("成功");
    }


    /**
    * @description 用户仓库删除，此接口会删除此仓库以及共享者的仓库
    * @param owner 拥有者
     * @param repository
    * @return com.woldier.check.common.R
    * @author: woldier
    * @date: 2023/3/6 9:19
    */
    @GetMapping("delete")
    public R delete(@RequestParam String owner, @RequestParam String repository) throws DoopfsException {
        repositoryService.delete_repo(owner,repository);
        return R.success("删除成功");
    }



}
